#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <poll.h>
#include <signal.h>

static int fd;

static void sig_handler(int signo)
{
	unsigned int key_val = 0;
    read(fd, &key_val, sizeof(key_val));
    if (0== key_val)
    {
        printf("key Press\n");
    }
    else if (1== key_val)
    {
        printf("key Release\n");
    }  
}

int main(int argc, char *argv[])
{ 
    int flag = 0;

    if (2 != argc)
    {
        printf("Usage: <device>\n\t./asyncKeyApp /dev/key\n");
        return -1;
    }
    fd = open(argv[1], O_RDONLY | O_NONBLOCK);
    if (0 > fd)
    {
        printf("open %s failed\n", argv[1]);
        return -1;
    }

    signal(SIGIO, sig_handler);
    fcntl(fd, F_SETOWN, getpid()); // 设置进程为fd的拥有者
    flag = fcntl(fd, F_GETFD);  // 获取当前的进程的属性
    fcntl(fd, F_SETFL, flag | FASYNC);
    while(1)
    {
        sleep(2);
    }
    close(fd);
    return 0;
}
/*
第 13 - 25行，sig_handler 函数，SIGIO 信号的处理函数，当驱动程序有效按键按下
以后就会发送 SIGIO 信号，此函数就会执行。此函数通过 read 函数读取按键状态数据，然后
通过 printf 函数打印在终端上。
第 43 行，通过 signal 函数设置 SIGIO 信号的处理函数为 sig_handler。
第 44~46 行，设置当前进程的状态，开启异步通知的功能。
第 47 行，for 循环，等待信号产生。
*/
